#include<iostream>
#include<func.h>
using std::endl;
using std::cout;

//注意是数组
//复习一下  server的写法
int main(int argc,char*argv[]){

    
    ARGS_CHECK(argc,3); //./server 192.168.213.128 8888
    //设置地址
    sockaddr_in sockaddr;
    sockaddr.sin_family = AF_INET; //IPV4
    sockaddr.sin_addr.s_addr = inet_addr(argv[1]);
    sockaddr.sin_port = htons(atoi(argv[2]));
    //创建socket
    int sockefd = socket(AF_INET,SOCK_STREAM,0);
    //设置地址复用
    int flag = 1;
    int ret = setsockopt(sockefd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));
    //端口复用
    ret = setsockopt(sockefd,SOL_SOCKET,SO_REUSEPORT,&flag,sizeof(flag));
    ret = bind(sockefd,(struct sockaddr *)&sockaddr,sizeof(sockaddr)); //注意bind前加struct 或者提前去好别名
    // 服务端 bind 只能绑定服务端地址
    ERROR_CHECK(ret,-1,"bind");
    //注意listen 
    listen(sockefd,100);

    //epoll部分
    int epfd = epoll_create(10);
    //准备好发送的buf
    char buf[4096];
    struct epoll_event event;
    //放入要监听的数据
    event.events = EPOLLIN; //读事件
    event.data.fd = sockefd; //监听读事件
    //准备好监听集合
    struct epoll_event readySet[10];
    bzero(&readySet,sizeof(readySet));
    //加入监听
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockefd,&event);
    int netfd = -1;
    while(1){
        //先等
        int readyNum = epoll_wait(epfd,readySet,10,-1);//一直等待
        //遍历就绪队列
        for(int i = 0;i < readyNum;++i){
            //说明来消息了
            //socket来的 并且是读事件
            if(readySet[i].data.fd == sockefd && readySet[i].events == EPOLLIN){
                //取出netfd 
                netfd = accept(sockefd,nullptr,nullptr);//不需要拿到客户端的地址（我这里选nulltpr）
                //添加netfd到就绪集合中
                //每次添加或者删除 event都要变
                event.events = EPOLLIN;
                event.data.fd = STDIN_FILENO;
                epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event);
                event.events = EPOLLIN;
                event.data.fd = netfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,netfd,&event);
                //移除监听
                epoll_ctl(epfd,EPOLL_CTL_DEL,sockefd,nullptr);
            }
            else if(readySet[i].data.fd == STDIN_FILENO){
                bzero(buf,sizeof(buf));
                ssize_t sret = read(STDIN_FILENO,buf,sizeof(buf));
                if(sret == 0){
                    send(netfd,"nishigehaoren",13,0);
                    close(netfd);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,netfd,NULL);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,STDIN_FILENO,NULL);
                    event.events = EPOLLIN;
                    event.data.fd = sockefd;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,sockefd,&event);
                    netfd = -1;
                    break;
                }
                send(netfd,buf,strlen(buf),0);
            }
            else if(readySet[i].data.fd == netfd){
                bzero(buf,sizeof(buf));
                ssize_t sret = recv(netfd,buf,sizeof(buf),0);
                if(sret == 0){
                    printf("Hehe\n");
                    close(netfd);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,netfd,NULL);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,STDIN_FILENO,NULL);
                    event.events = EPOLLIN;
                    event.data.fd = sockefd;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,sockefd,&event);
                    netfd = -1;
                    break;
                }
                printf("buf = %s\n", buf);
            }
        }
    }
    return 0;
}


